package com.jy.modules.cims.creditright.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.common.sysUtils.SimpleStringUtils;
import com.jy.modules.cims.component.balance.MathFormulaUtils;
import com.jy.modules.cims.component.common.service.TCMmCreditDetailService;
import com.jy.modules.cims.contract.service.ContractService;
import com.jy.modules.cims.data.common.dto.TCMmCreditDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditSettleParamDTO;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.credit.CreditApplyDto;
import com.jy.modules.platform.sysdict.impl.SysDictAPImpl;
import com.jy.platform.api.sysdict.SysDictDetailVo;

/**
 * 
 * ClassName: CreditDealImportCheckService 
 * @Description: 受让债权导入验证
 * @author zhangmi
 * @date 2015-8-13
 */
@Service("com.jy.modules.cims.creditright.service.CreditDealImportCheckService")
public class CreditDealImportCheckService {
	

	//private static List<Map> idTypeList = null;
	//private static List<Map> repayTypeList = null;
	private static BigDecimal REPAY_ERROR_RATE = BigDecimal.valueOf(0.02); 

	@Autowired
	private SysDictAPImpl sysDictAPI;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.contract.service.ContractService")
	private ContractService contractService;
	

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditDetailService")
	private TCMmCreditDetailService tcmmCreditDetailService;
	
	/**
	 * 
	 * @Description 验证债权受让excel数据是否准确
	 * @param creditDetailList
	 * @throws Exception   
	 * void  
	 * @throws
	 * @author zhangmi
	 * @date 2015-8-13R
	 */
	public void doImportCheck(List<CreditDetailDto> creditDetailList,CreditApplyDto dto) throws Exception{
		
		int start = dto.getStatementDateStart();
		int end = dto.getStatementDateEnd();
		String repayType = "";
		int cnt = 0;
		
		if(CollectionsUtils.isNotEmpty(creditDetailList)&& creditDetailList.size()>500){
			throw new Exception("最多不能超过500条数据！");
		}
		//根据包号，债权来源，合约编号查询债权信息
		String cooperorgCode = CimsConstant.COOPERORG_CODE_JY.equals(dto.getTransfereeCode()) ? dto.getTransferorCode() : dto
				.getTransfereeCode();
		TCMmCreditDetailDTO searchDto = new TCMmCreditDetailDTO();
		searchDto.setPackageNum(dto.getPackageNum());
		searchDto.setContractCode(dto.getContractCode());
		searchDto.setCreditSource(CimsConstant.CREDIT_SOURCE_REC);
		searchDto.setCooperorgCode(cooperorgCode);
		List<TCMmCreditDetailDTO> list = tcmmCreditDetailService.searchTCMmCreditDetail(SearchParamUtil.getSearchParam(searchDto));
		if((list.size()+creditDetailList.size())>5000){
			throw new Exception("同一个债权包下最多不能超过5000条数据！");
		}
		for (CreditDetailDto creditDetailDto : creditDetailList) {
			
			/*if(creditDetailDto.getPlanRedeemDate()==null){
				throw new Exception("第"+(cnt+2)+"行数据不合法，计划赎回日期不能为空！");
			}*/
			
			if(!SimpleStringUtils.hasText(creditDetailDto.getBorrowerName())){
				throw new Exception("第"+(cnt+2)+"行数据不合法，借款人姓名不能为空！");
			}
			if(!SimpleStringUtils.hasText(creditDetailDto.getBorrowerIdNumber())){
				throw new Exception("第"+(cnt+2)+"行数据不合法，借款人身份证不能为空！");
			}
			if(creditDetailDto.getContractSum()==null){//合同金额
				throw new Exception("第"+(cnt+2)+"行数据不合法，合同金额不能为空！");
			}
			if(creditDetailDto.getLoanSum()==null){//放款金额
				throw new Exception("第"+(cnt+2)+"行数据不合法，放款金额不能为空！");
			}
			if(creditDetailDto.getBillDate()==null){//账单日
				throw new Exception("第"+(cnt+2)+"行数据不合法，账单日不能为空！");
			}
			long billDate = creditDetailDto.getBillDate();
			if(!(start<=billDate&&billDate<=end)){
				throw new Exception("第"+(cnt+2)+"行数据不合法，账单日必须在："+start+"-"+end+"之间！");
			}
			Date repayStartDate = creditDetailDto.getRepayStartDate();//还款起始日期
			if(repayStartDate==null){
				throw new Exception("第"+(cnt+2)+"行数据不合法，还款起始日期不能为空！");
			}
			Date initialLoanDate = creditDetailDto.getInitialLoanDate();
			if(initialLoanDate==null){//初始放款日期
				throw new Exception("第"+(cnt+2)+"行数据不合法，初始放款日期不能为空！");
			}
			if(!repayStartDate.after(initialLoanDate)){
				throw new Exception("第"+(cnt+2)+"行数据不合法，还款起始日期要比初始放款日期大！");
			}
			if(creditDetailDto.getDeliverDate()==null){//交割日期
				throw new Exception("第"+(cnt+2)+"行数据不合法，交割日期不能为空！");
			}
			if(creditDetailDto.getThisRepaySum()==null){//本期还款金额
				throw new Exception("第"+(cnt+2)+"行数据不合法，本期还款金额不能为空！");
			}
			if(creditDetailDto.getCooperorgTransferId()==null){//合作机构债权编号
				throw new Exception("第"+(cnt+2)+"行数据不合法，合作机构债权编号不能为空！");
			}
			Long repayPeriod = creditDetailDto.getRepayPeriod();
			Long residueRepayPeriod = creditDetailDto.getResidueRepayPeriod();
			if(repayPeriod==null){//还款期数
				throw new Exception("第"+(cnt+2)+"行数据不合法，还款期数不能为空！");
			}
			if(residueRepayPeriod==null){//剩余还款期数
				throw new Exception("第"+(cnt+2)+"行数据不合法，剩余还款期数不能为空！");
			}
			if(repayPeriod<1){
				throw new Exception("第"+(cnt+2)+"行数据不合法，还款期数不能小于1！");
			}
			if(residueRepayPeriod<1){
				throw new Exception("第"+(cnt+2)+"行数据不合法，剩余还款期数不能小于1！");
			}
			if(residueRepayPeriod>repayPeriod){
				throw new Exception("第"+(cnt+2)+"行数据不合法，剩余还款期数不能大于还款期数！");
			}
			if(creditDetailDto.getLoanMonthlyinterest()==null){//月利率
				throw new Exception("第"+(cnt+2)+"行数据不合法，月利率不能为空！");
			}
			String monthRate = creditDetailDto.getLoanMonthlyinterest().toString();
			if(!startCheck(monthRate)){
				throw new Exception("第"+(cnt+2)+"行数据不合法，月利率必须小于6位小数！");
			}
			if(creditDetailDto.getMakeCreditorValue()==null){//转让债权价值
				throw new Exception("第"+(cnt+2)+"行数据不合法，转让债权价值不能为空！");
			}
			if(!SimpleStringUtils.hasText(creditDetailDto.getLoanProductName())){//产品类型
				throw new Exception("第"+(cnt+2)+"行数据不合法，产品类型不能为空！");
			}
//			if(!StringUtils.hasText(creditDetailDto.getRepaymentDateCalculation())){//还款日计算方
//				throw new Exception("还款日计算方不能为空！");
//			}
			if(creditDetailDto.getRepayType()==null||
					!checkDictDetailValue2(CimsConstant.DICT_REPAYMENTWAY,creditDetailDto.getRepayType())){//还款方式
				throw new Exception("第"+(cnt+2)+"行数据不合法，还款方式为空或者该还款方式不存在！");
			}
			//验证还款方式是否一致
			if(cnt==0){
				repayType = creditDetailDto.getRepayType();
			}else{
				if(!repayType.equals(creditDetailDto.getRepayType())){
					throw new Exception("第"+(cnt+2)+"行数据不合法，模板数据的还款方式必须保持一致！");
				}
			}
			if(creditDetailDto.getCardType()==null||
					!checkDictDetailValue2(CimsConstant.DICT_IDTYPE,creditDetailDto.getCardType())){//证件类型
				throw new Exception("第"+(cnt+2)+"行数据不合法，证件类型为空或者该证件类型不存在！");
			}
			//月还计算误差值
			BigDecimal jsRepay = MathFormulaUtils.Math_MonthRepay_RT01(creditDetailDto.getLoanMonthlyinterest(), creditDetailDto.getContractSum(), repayPeriod.intValue());
			if(jsRepay.doubleValue()<=0){
				throw new Exception("第"+(cnt+2)+"行数据不合法，导入本期月还计算金额小于等于0！");
			}
			if(!checkRepayAmount(creditDetailDto.getThisRepaySum(), jsRepay,repayType)){
				throw new Exception("第"+(cnt+2)+"行数据不合法，导入本期还款金额和系统计算的误差大于2%！");
			}
			
			//如果是身份证号码类型
//			if("1".equals(creditDetailDto.getCardType())){
//				String resultMsg = IdCardUtils.isValidatedAllIdcard(creditDetailDto.getBorrowerIdNumber().trim());
//				if(StringUtils.hasText(resultMsg)){
//					throw new Exception("第"+(cnt+2)+"行数据不合法，"+resultMsg);
//				}
//			}else if("6".equals(creditDetailDto.getCardType())){//如果数值字典证件类型编码为6，过滤证件类型
//				creditDetailDto.setCardType("1");//设置为身份证类型
//			}
			cnt++;
		}
		if(!checkRepayType(repayType,dto.getContractCode())){
			throw new Exception("模板数据的还款方式和合约配置的还款方式不匹配！");
		}
	}
	
	/**
	 * 
	 * @Description 验证类型是否存在
	 * @param dict_code
	 * @param dict_value
	 * @return   
	 * boolean  
	 * @throws
	 * @author zhangmi
	 * @date 2015-8-13
	 */
	public boolean checkDictDetailValue(String dict_code,String dict_value){
		SysDictDetailVo dict = sysDictAPI.queryDetailByDictCodeAndDeatailValue(dict_code, dict_value);
		if(dict!=null&&SimpleStringUtils.hasText(dict.getDictDetailValue())){
			return true;
		}
		return false;
	}
	
	/**
	 * 
	 * @Description  验证类型是否存在 （高性能）
	 * @param dict_code
	 * @param dict_value
	 * @throws
	 * @author zhangmi
	 * @date 2015-8-13
	 */
	public boolean checkDictDetailValue2(String dictCode,String dictValue){
		if(CimsConstant.DICT_REPAYMENTWAY.equals(dictCode)){//验证还款方式
			List<Map> 	repayTypeList = sysDictAPI.getDictByKey(dictCode);
			for (Map map : repayTypeList) {
				if(dictValue.equals(map.get("DICVALUE").toString())){
					return true;
				}
			}
		}else if(CimsConstant.DICT_IDTYPE.equals(dictCode)){//验证证件类型
			List<Map> 	idTypeList = sysDictAPI.getDictByKey(dictCode);
			for (Map map : idTypeList) {
				if(dictValue.equals(map.get("DICVALUE").toString())){
					return true;
				}
			}
		}
		return false;
	}
	/**
	 * 验证合约结算参数，和模板结算参数是否一致
	 * @param repayType
	 * @return
	 * @throws Exception   
	 * boolean  
	 * @throws
	 * @author zhangmi
	 * @date 2016-3-4
	 */
	public boolean checkRepayType(String repayType,final String contractCode) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		List<TCMmCreditSettleParamDTO> list = contractService.getCreditSettleList(contractCode);
		for (TCMmCreditSettleParamDTO tcMmCreditSettleParamDTO : list) {
			String key = tcMmCreditSettleParamDTO.getRepayType();
			map.put(key, key);
		}
		if(map.containsKey(repayType)){
			return true;
		}
		return false;
	}
	
	/**
	 * 
	 * @Description 校验导入月还金额，和实际计算的金额误差小于2%
	 * @param impRepay
	 * @param jsRepay
	 * @return   
	 * boolean  
	 * @throws
	 * @author zhangmi
	 * @date 2016-7-8
	 */
	public boolean checkRepayAmount(BigDecimal impRepay,BigDecimal jsRepay,String repayType){
		//只验证等额本息
		if(CimsConstant.DYD_REFUND_TYPE_DEBX.equals(repayType)||"AC10001".equals(repayType)){
			BigDecimal rcAmount = impRepay.multiply(REPAY_ERROR_RATE);
			double sjAmount = Math.abs(jsRepay.doubleValue()-impRepay.doubleValue());
			//实际出错金额小于等于 容错金额
			if(sjAmount <= rcAmount.doubleValue()){
				return true;
			}
		}else{
			return true;
		}
		return false;
	}
	/**
	 * 正则表达式：验证月还利率
	 * @Title startCheck
	 * @Description TODO
	 * @param string
	 * @return 
	 * boolean 
	 * @author zhangmi
	 * @date 2016-7-27-下午5:02:22
	 * @update 
	 * @throws
	 */
	public static boolean startCheck(String string)  
    {  
        boolean tem=false;  
          
        Pattern pattern = Pattern.compile("^[0]{1}+(.[0-9]{1,6})?$");  
        Matcher matcher=pattern.matcher(string);  
          
        tem=matcher.matches();  
        return tem;  
    }  
}
